1 module hip.graphics.g2d.profiling;
2 
3 /**
4  * Draw GC stats on screen for instant feedback.
5  * Params:
6  *   x = X position
7  *   y = Y Position. If it is < 0, it will draw at the default Y which is in the lower part of the screen
8  */
9 void drawGCStats(int x = 0, int y = -1)
10 {
11     import hip.config.opts;
12     import hip.util.string;
13     import hip.util.data_structures;
14     import hip.math.utils;
15     import hip.graphics.g2d.renderer2d;
16      if(x < 0)
17         x = 0;
18     if(y < 0)
19     {
20         import hip.hiprenderer.renderer;
21         y = HipRenderer.getCurrentViewport.worldHeight;
22     }
23 
24     static struct ByteUnit
25     {
26         double data;
27         string unit;
28 
29         SmallString asSmallString() @nogc
30         {
31             return SmallString(
32                 SmallString(data).toString.limitDecimalPlaces(2),
33                 unit
34             );
35         }
36     }
37 
38     ByteUnit formatFromBytes(size_t byteCount) @nogc
39     {
40         double actualResult = byteCount;
41 
42         if(actualResult <= 1000)
43             return ByteUnit(floorDecimal(actualResult, 2), " B");
44         actualResult/= 1000;
45         if(actualResult <= 1000)
46             return ByteUnit(floorDecimal(actualResult, 2), " KB");
47         actualResult/= 1000;
48             return ByteUnit(floorDecimal(actualResult, 2), " MB");
49         actualResult/= 1000;
50         return ByteUnit(floorDecimal(actualResult, 2), " GB");
51     }
52 
53     static if(CustomRuntime)
54     {
55         import core.arsd.memory_allocation;
56         SmallString str = SmallString("Memory Allocated ", formatFromBytes(getMemoryAllocated()).asSmallString().toString);
57         drawText(str.toString, x, y, 1.0,  HipColor(0,50,0), HipTextAlign.botLeft);
58 
59     }
60     else
61     {
62         import core.memory;
63         GC.Stats stats = GC.stats;
64         GC.ProfileStats prof = GC.profileStats;
65         SmallString timeOnPause = SmallString.get();
66         SmallString timeOnCollection = SmallString.get();
67 
68         prof.totalPauseTime.toString((string data)
69         {
70             timeOnPause~= data;
71         });
72         prof.totalCollectionTime.toString((string data)
73         {
74             timeOnCollection~= data;
75         });
76 
77 
78         scope BigString str = BigString(
79             "Memory Used: ", formatFromBytes(stats.usedSize).asSmallString.toString,
80             "\nFree Memory: ", formatFromBytes(stats.freeSize).asSmallString.toString,
81             "\nPaused Time: ", timeOnPause.toString,
82             "\nCollection Time:", timeOnCollection.toString,
83             "\nCollections Count: ", prof.numCollections,
84         );
85         drawText(str.toString, x, y, 1.0,  HipColor(0, 0, 0, 150), HipTextAlign.botLeft);
86     }
87 }
88 
89 
90 private __gshared float lastTiming;
91 private __gshared float lastTime;
92 private __gshared int count;
93 private __gshared immutable countReset = 30;
94 
95 void setFrameInitTime()
96 {
97     import hip.util.time;
98     if(++count == countReset)
99     {
100         lastTime = HipTime.getCurrentTimeAsMs();
101         count = 0;
102     }
103 }
104 void drawTimings(int x = -1, int y = 0, bool clearTiming = false)
105 {
106     import hip.util.time;
107     import hip.util.string;
108     import hip.graphics.g2d.renderer2d;
109 
110     if(count == 0)
111         lastTiming = HipTime.getCurrentTimeAsMs() - lastTime;
112     SmallString timeProcessing = SmallString("CPU Time: ", SmallString(lastTiming).toString.limitDecimalPlaces(3), "ms");
113 
114     if(x == -1)
115         x = getCurrentViewport().worldWidth;
116 
117     drawText(timeProcessing.toString, x, 0, 1.0f, HipColor.white, HipTextAlign.topRight);
118 
119     // if(clearTiming)
120     //     lastTime = currTime;
121 }